﻿#pragma once
namespace JOUI
{
	// 图像像素数据结构
	struct info_bitmapdata
	{
		UINT width;
		UINT height;
		INT stride;
		INT pixelFormat;
		BYTE* scan0;
		LPVOID reserved;
	};
	class TOAPI UIImage
	{
	public:
		UIImage() = default;
		//创建空白图像
		UIImage(INT width, INT height);
		//图像创建自文件
		UIImage(LPCWSTR file);
		//图像创建自位图句柄
		UIImage(HBITMAP hBitmap, HPALETTE hPalette, BOOL fPreAlpha);
		//图像创建自图标句柄
		UIImage(HICON hIcon);
		//图像创建自内存、缓冲区
		UIImage(LPVOID data, size_t size);
		UIImage(INT nWidth, INT nHeight, BYTE* pbBuffer);
		//图像创建自WIC资源
		UIImage(IWICBitmap* src_bitmap);
		UIImage(ID2D1Image* src_bitmap, D2D1_SIZE_U size);
		//创建自字节流
		UIImage(LPSTREAM lpStream);
		/*
		* @brief 图像创建自SVG
		* @param ourcefile 文件路径或代码内容
		* @param fCode 是否代码内容
		* @param color 指定颜色
		* @param uiWidth 指定宽度
		* @param uiHeight 指定高度
		*/
		UIImage(LPCWSTR ourcefile, BOOL fCode, UINT uiWidth = 100, UINT uiHeight = 100, UIColor color = {});
		//图像创建自资源包 zFile为0取默认主题
		UIImage(UIZip* hRes, LPCWSTR fileName);
		~UIImage();
		/*
		* @brief 加载图标、光标、位图句柄自内存;此方法不会创建到图像对象
		* @param uType 类型：参考IMAGE_开头
		* @param nIndex 接收下一帧延时
		*/
		static HANDLE LoadFromMemoryHandle(LPVOID lpData, size_t dwLen, INT uType = IMAGE_ICON, INT nIndex = 0);
		//置动态图像当前活动帧
		HRESULT SetCurFrame(INT index);
		//取动态图像当前活动帧
		UINT GetCurFrame();
		//取动态图像帧数
		UINT GetFrameCount();
		//取图像尺寸
		HRESULT GetSize(UINT& Width, UINT& Height);
		/* @brief 到动态图像下一帧
		 * @param r_next_index 接收下一帧索引
		 * @param r_next_delay 接收下一帧延时
		*/
		HRESULT NextFrame(UINT* r_next_index = nullptr, UINT* r_next_delay = nullptr);
		//取动态图像当前帧延时
		BOOL GetFrameDelay(INT& lpDelayAry, INT nFrames);
		/* @brief 锁定图像
		 * @param lpRectL 锁定区域(为NULL整个图)
		 * @param flags 1读 2写 3读写
		 * @param PixelFormat 图像格式 PixelFormat32bppARGB
		 * @param lpLockedBitmapData 接收锁定信息
		*/
		HRESULT Lock(RECT* lpRectL, DWORD flags, INT PixelFormat, info_bitmapdata** lpLockedBitmapData);
		/* @brief 解锁图像
		 * @param lpLockedBitmapData 锁定信息
		*/
		HRESULT UnLock(info_bitmapdata* lpLockedBitmapData);
		/* @brief 取点颜色
		 * @param x,y 坐标
		 * @param r_color 接收对应点UIColor颜色
		*/
		HRESULT GetPixel(INT x, INT y, UIColor& r_color);
		/* @brief 置点颜色
		 * @param x,y 坐标
		 * @param color UIColor颜色
		*/
		HRESULT SetPixel(INT x, INT y, UIColor color);
		/* @brief 复制图像
		 * @param r_dest 接收新图像对象
		 * @param copy_rect 复制的图像区域
		*/
		HRESULT Copy(UIImage** r_dest, RECT* copy_rect = nullptr);
		/* @brief 拉伸图像
		 * @param new_width 新宽度
		 * @param new_height 新高度
		 * @param r_dest 接收新图像对象
		 * @param copy_rect 复制的图像区域
		*/
		HRESULT Scale(UINT new_width, UINT new_height,
			UIImage** r_dest, RECT* copy_rect = nullptr);
		/*
         * @brief 翻转图像
         * @param rfType                  [INT]                 参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms534171(v=vs.85).aspx
         * @param r_dest                  [UIImage]             返回新图像对象
         * @return [BOOL]返回是否成功
         */
		BOOL Rotateflip(INT rfType, UIImage** r_dest);
		//取图像上下文
		LPVOID GetContext();
		/*
         * @brief 图像保存
         * @param format   0png,1jpeg,2bmp,3ico,4tiff,5,gif,6wmp,7dds,8aang,9webp,10heif
         * @return [BOOL]返回是否成功
         */
		BOOL Save(LPVOID& lpBuffer, size_t& len, INT format = 0);
		BOOL Save(LPCWSTR wzFileName, INT format = 0);

	protected:
		UINT m_width = 0;
		UINT m_height = 0;
		UINT m_frame_count = 0;
		UINT m_cur_frame = 0;
		ID2D1Bitmap* m_d2d_bitmap = nullptr;
		IWICBitmap* m_wic_bitmap = nullptr;
		IWICBitmapDecoder* m_WicDecoder = nullptr;

		void wic_init_from_decoder(IWICBitmapDecoder* pDecoder);
		void wic_drawframe(IWICBitmapSource* pFrame, D2D1_RECT_F* dest);
		void wic_createfromstream(LPSTREAM lpStream);
		void wic_createfromsvg(LPCWSTR ourcefile, BOOL fCode, UINT uiWidth, UINT uiHeight, UIColor color);
		void wic_createfrommemory(LPVOID data, size_t size);
		void wic_createfrompngbits(INT nWidth, INT nHeight, BYTE* pbBuffer);

	};
}
